//sql_index.cpp

#ifndef _SQL_INDEX_CPP_
#define _SQL_INDEX_CPP_


#include "sql_index.h"
#include "../include/utils.h"
#include <fstream>
#include <stdint.h>
#include <vector>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>


/* CommonIndex */

DBIndex::CommonIndex::CommonIndex(){
    this->bplustree = nullptr;
}

DBIndex::CommonIndex::CommonIndex(const std::string index_name,const std::string table_name,const std::string define_sql){
    this->index_name = index_name;
    this->table_name = table_name;
    this->define_sql = define_sql;
    //系统不自动添加
    this->bplustree = nullptr;
}


/* IndexKeeper */
DBIndex::IndexKeeper::IndexKeeper(){
    this->index_vis.clear();
    this->allIndex.clear();
}

void DBIndex::IndexKeeper::flush(){
    this->index_vis.clear();
    this->allIndex.clear();
}

//添加索引
//成功0 失败-1
int DBIndex::IndexKeeper::addIndex(const std::string tablename,
const std::string indexname,const std::string _sql){
    if(this->hasIndex(indexname)){
        printf("[error]-has exist this index\n");
        return -1;
    }
    //添加索引
    DBIndex::CommonIndex one;
    one.table_name = tablename;
    one.index_name = indexname;
    one.define_sql = _sql;
    this->index_vis[indexname] = 1;
    this->allIndex[indexname] = one;
    return 0;
}

//删除索引
//成功0 失败-1
int DBIndex::IndexKeeper::delIndex(const std::string indexname){
    if(this->hasIndex(indexname)){
        //删除索引
        DBIndex::CommonIndex one;//置成空
        this->allIndex[indexname] = one;
        this->index_vis[indexname] = 0;
        return 0;
    }
    printf("[error]-not find this index\n");
    return -1;
}


//查找索引存在性
//成功1 失败0
int DBIndex::IndexKeeper::hasIndex(const std::string indexname){
    return this->index_vis[indexname] == 1 ? 1 : 0;
}

//获取索引表的索引信息
//vector< vector<string(索引名),string(表名),string(sql语句) >
std::vector<std::vector<std::string> > 
DBIndex::IndexKeeper::getIndexOnTable(const std::string tbname){
    std::vector<std::vector<std::string> > ans;
    std::map<std::string,int>::iterator iter;
    iter = this->index_vis.begin();
    while(iter != this->index_vis.end()){
        if(iter->second == 1){
            std::string index_name = iter->first;
            DBIndex::CommonIndex one = this->allIndex[index_name];
            if(one.table_name == tbname){
                std::vector<std::string> line;
                line.push_back(one.index_name);
                line.push_back(one.table_name);
                line.push_back(one.define_sql);
                ans.push_back(line);
            }
        }
        iter++;
    }
    return ans;
}

//删除某个表涉及的所有索引
int DBIndex::IndexKeeper::deleteIndexOnTable(const std::string tbname){
    std::vector<std::string> del_list;//需要删除的索引名称
    std::map<std::string,int>::iterator iter;
    iter = this->index_vis.begin();
    while(iter != this->index_vis.end()){
        if(iter->second == 1){
            std::string index_name = iter->first;
            DBIndex::CommonIndex one = this->allIndex[index_name];
            if(one.table_name == tbname){
                del_list.push_back(index_name);
            }
        }
        iter++;
    }
    //删除开始
    int lenth = del_list.size();
    for(int i=0;i<lenth;i++){
        std::string index_name = del_list[i];
        this->delIndex(index_name);
    }
    return 0;
}


//获取所有记录中的索引
//vector< vector<string(索引名),string(表名),string(sql语句)> >
std::vector<std::vector<std::string> > DBIndex::IndexKeeper::getAllIndex(){
    std::vector<std::vector<std::string> > ans;
    std::vector<std::string> header = {"index_name","table","SQL"};
    ans.push_back(header);
    //
    std::map<std::string,int>::iterator iter;
    iter = this->index_vis.begin();
    while(iter != this->index_vis.end()){
        if(iter->second == 1){
            std::string index_name = iter->first;
            DBIndex::CommonIndex one = this->allIndex[index_name];
            //组装
            std::vector<std::string> line;
            line.push_back(one.index_name);
            line.push_back(one.table_name);
            line.push_back(one.define_sql);
            ans.push_back(line);
        }
        iter++;
    }
    if(ans.size() == 1) { ans.clear(); }
    return ans;
}


const std::string index_path = "../data/db.index";

int DBIndex::IndexKeeperReader(IndexKeeper& rhs){
    rhs.flush();
    std::fstream inner;
    inner.open(index_path,std::ios::in);
    std::string line = "";
    while(getline(inner,line)){
        int lenth = line.size();
        if(lenth > 0){
            if(line[0] != '#'){
                //获取索引名
                std::string index_name = SavenUtils::Split_first(line,"$$");
                index_name = SavenUtils::trim(index_name);
                line = SavenUtils::Split_second(line,"$$");
                //获取表名
                std::string tbname = SavenUtils::Split_first(line,"$$");
                tbname = SavenUtils::trim(tbname);
                //获取sql语句
                line = SavenUtils::Split_second(line,"$$");
                std::string sql_one = SavenUtils::trim(line);
                //添加
                rhs.addIndex(tbname,index_name,sql_one);
            }
        }
    }
    inner.close();
    return 0;
}


int DBIndex::IndexKeeperWriter(IndexKeeper& rhs){
    std::fstream outer;
    outer.open(index_path,std::ios::out);
    //vector< vector<string(索引名),string(表名),string(sql语句)> >
    std::vector<std::vector<std::string> > allinfo = rhs.getAllIndex();
    int lenth = allinfo.size();
    if(lenth <= 0){
        outer.close();
        return 0;
    }
    for(int i=1;i<lenth;i++){
        std::vector<std::string> line = allinfo[i];
        int len = line.size();
        // printf("once------\n");
        if(len == 3){
            outer << line[0] << "$$" << line[1] << "$$" << line[2] << "\n";
        }
    }
    outer.close();
    return 0;
}




#endif //_SQL_INDEX_CPP_
